home *** CD-ROM | disk | FTP | other *** search
- ;* MEMMGR.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Initialise and support the paging system *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
-
- DATASEG
- EXTRN _top:word
-
- paragraphnum DW 0 ; # of paragraphs of memory available
- firstparagraph DW 0 ; first actually used para. for Scheme heap
- first_dos DW 0 ; first DOS para. for Scheme heap
- emshandle DW 0ffffh
- emspages DB 0
-
- UDATASEG
- emsframe DW ?
- emsbias DB ?
- defpagesize DW ?
-
- CODESEG
- ;======================================================================
- ;
- ; Get page base address of page
- ;
- ; On exit, carry is clear to indicate page is always in memory
- ; (for compatibility with extended and expanded versions of this routine)
- ;
- ;======================================================================
-
- PROC C getbase, @@base:word
- mov bx, [@@base]
- mov ax, [pagetable+bx] ; Get table indicator
- clc ; always succeeds
- ret
- ENDP
-
- ;======================================================================
- ;
- ; InitMem()
- ; Compute the best page size, but not smaller than MIN_PAGESIZE
- ;
- ;======================================================================
- PROC C initmem USES si di
- LOCAL @@paraspepage, @@freepages
-
- push ds ;Assume es = ds
- pop es
-
- action <Seeking for free memory',13,10,'>
- mov bx, 0ffffh ; first ask for too much
- mov ah, 048h
- int MSDOS ; DOS gets an error, but tells us
- ; in bx how much we CAN get
- action <Allocating conventional memory',13,10,'>
- mov [paragraphnum], bx
- mov ah, 048h
- int MSDOS ; reissue allocation request
- mov [first_dos], ax ; save address for returning it to DOS
- mov [firstparagraph], ax ; save address for Scheme heap
-
- action <Trying to allocate expanded memory',13,10,'>
- mov ax, 3500h or EMMINT
- int MSDOS
- mov di, 10
- DATASEG
- @@emmname DB 'EMMXXXX0'
- EMMLENGTH = $ - @@emmname
- CODESEG
- lea si, [@@emmname]
- mov cx, EMMLENGTH
- repe cmpsb
- jne @@noems
- mov ah, 40h
- int EMMINT
- or ah, ah
- jnz @@noems
- mov ah, 41h
- int EMMINT
- or ah, ah
- jnz @@noems
- mov [emsframe], bx
- mov ah, 42h
- int EMMINT
- or ah, ah
- jnz @@noems
- cmp bx, MAXEMS
- jb @@takeallofem
- mov bx, MAXEMS
- @@takeallofem:
- action <Allocating EMS... >
- mov [emspages], bl
- mov ah, 43h
- int EMMINT
- or ah, ah
- jnz @@noems
- mov [emshandle], dx
- action <EMS memory allocated',13,10,'>
-
- @@noems:
- action <Compute best page size',13,10,'>
- mov ax, [firstparagraph]
- add ax, [paragraphnum] ; max number of paragraphs
- xchg ax, [paragraphnum]
- xor dx, dx ; get ready for divide
- mov cx, NUMPAGES-PREALLOC
- sub cl, [emspages] ; cx <= number heap allocated pages
- mov [@@freepages], cx
- div cx ; ax <= paras-per-page
-
- cmp ax, MIN_PAGESIZE shr 4
- jge @@longpages
- mov ax, MIN_PAGESIZE shr 4
- @@longpages:
- cmp ax, 800h
- jb @@nottoobig
- mov ax, 7ffh ; when page sizes become negative...
- @@nottoobig:
- mov [@@paraspepage], ax
- mov cx, 4 ; compute page size
- shl ax, cl
- mov [defpagesize], ax
- mov si, ax
-
- action <Initialize page management table... >
- xor cx, cx ; number of pages
- mov dx, [nextpage]
- mov [freepage], dx
- mov ax, [firstparagraph] ; ax <= next paragraph
- mov di, [paragraphnum] ; di <= (paragraphnum - paras per page)
- sub di, [@@paraspepage]
- @@loop:
- cmp di, ax ; Did we reach it ?
- jb @@done
- cmp cx, [@@freepages] ; See if we have filled the table
- jae @@done
- mov bx, dx
- shl bx, 1
- mov [pagetable+bx], ax
- mov [psize+bx], si
- and [attrib+bx], not NOMEMORY
- inc dx
- mov [pagelink+bx], dx
- mov [nextcell+bx], 0
- inc cx ; one more page done
- add ax, [@@paraspepage] ; next block
- jmp @@loop
- @@done:
- mov al, [emspages]
- mov ah, dl
- shl ah, 1
- sbb ah, 0 ; in case we overflowed to 0,
- mov [emsbias], ah ; put 0xff instead
- @@ems:
- cmp al, 0
- je @@emsdone
- cmp dx, NUMPAGES
- je @@emsdone
- action <EMS... >
- mov bx, dx
- shl bx, 1
- mov [pagetable+bx], EMSPAGE
- mov [psize+bx], EMSSIZE
- and [attrib+bx], not NOMEMORY
- inc dx
- mov [pagelink+bx], dx
- mov [nextcell+bx], 0
- inc cx ; one more page done
- dec al
- jmp @@ems
- @@emsdone:
- action <',13,10,'Exiting memory allocation subroutine',13,10,'>
- sub [emspages], al ; we'll waste these
- mov [nextpage], dx ; nextpage = lastpage
- mov [lastpage], dx
- mov ax, cx
- ret
- ENDP initmem
-
- MACRO bubble from, to
- LOCAL @@skip
- cmp bl, [ss:@@frame+from]
- jne @@skip
- xchg bl, [ss:@@frame+to]
- xchg [ss:@@frame+from], bl
- @@skip:
- ENDM
-
- MACRO copy from, to
- mov al, [ss:@@frame+from]
- mov [ss:@@frame+to], al
- ENDM
-
- PROC loadems
- DATASEG
- @@frame db 4 dup (0ffh)
- CODESEG
- ; our purpose is to map page bx/2 to some place in expanded memory,
- ; returning a valid segment address in [pagetable+bx]
- ;NOTE: we may not assume anything about ds ! all addressing must be
- ;done relative to ss ('small data' model)
- push ax
- mov ax, [ss:pagetable+bx]
- cmp ax, EMSPAGE
- je @@newpage
- bubble 3, 2
- bubble 2, 1
- bubble 1, 0
- pop ax
- ret
- @@newpage:
- push bx
- mov bl, 4
- @@loop:
- cmp [ss:@@frame+bx-1], 0ffh
- jne @@found
- dec bx
- jnz @@loop
- @@found:
- cmp bl, 4
- jne @@usebl ; now we gotta discard the oldest page
- mov bl, [ss:@@frame+3]
- mov ax, EMSPAGE
- xchg ax, [ss:pagetable+bx]
- sub ax, [ss:emsframe]
- shr ax, 1
- shr ax, 1
- mov bl, ah
- @@usebl: ; let's work on physical page bl
- mov al, bl
- pop bx ; get the page to load
- push bx dx ax
- mov ah, 44h ; EMS map pages
- sub bl, [ss:emsbias]
- shr bx, 1
- mov dx, [ss:emshandle]
- int EMMINT
- pop ax dx bx ; this is the physical page #
- mov ah, al
- xor al, al
- shl ax, 1
- shl ax, 1
- add ax, [ss:emsframe]
- mov [ss:pagetable+bx], ax ; now write this value, so it can
- ; be found immediately next time
- copy 2, 3
- copy 1, 2
- copy 0, 1
- mov [ss:@@frame+0], bl
- pop ax
- ret
- ENDP loadems
-
- END